package br.com.vti.leilao.model.business;

import br.com.vti.leilao.model.business.exception.ApplicationException;
import br.com.vti.leilao.model.dao.Dao;
import br.com.vti.leilao.model.entity.Model;
import br.com.vti.leilao.view.util.MessageFactory;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Interface de negócio genérica para manipulação do objeto de dominio. 
 * 
 * @author Ednardo Rubens
 * 
 * @param <E> entidade extends Model
 * @param <X> exceção extends Exception
 * 
 */
public interface Business<E extends Model<? extends Number>, X extends ApplicationException> extends Serializable {

    public static final int INSERIR = 1;
    public static final int REMOVER = 2;
    public static final int ATUALIZAR = 3;
    public static final int BUSCAR = 4;
    public static final int LISTAR = 5;

    /**
     * Retorna o dao utilizado pela classe de negócio
     * @return dao utilizado para gravar as informações no banco
     */
    Dao<E> getDao();

    /**
     * Seta o dao utilizado pela classe de negócio
     * @param dao Dao<E>
     */
    void setDao(Dao<E> dao);

    /**
     * Retorna o messageFactory que será utilizado para buscar as mensagens
     * @return MessageFactory
     */
    MessageFactory getMessageFactory();

    /**
     * Seta o messageFactory que será utilizado para buscar as mensagens
     * @param messageFactory MessageFactory
     */
    void setMessageFactory(MessageFactory messageFactory);

    /**
     * Método reponsável pela inclusão de uma entidade no banco
     * @param entidade Entidade
     * @throws X
     */
    void inserir(E entidade) throws X;

    /**
     * Método reponsável pela atualização de uma entidade no banco
     * @param entidade Entidade
     * @throws X
     */
    void atualizar(E entidade) throws X;

    /**
     * Método reponsável pela exclusão de uma entidade no banco
     * @param entidade Entidade
     * @throws X
     */
    void remover(E entidade) throws X;

    /**
     * Procura uma entidade no banco por id
     * @param entidade Entidade buscada no banco
     * @return entidade
     * @throws X
     */
    E procurarPorId(E entidade) throws X;

    /**
     * Lista todos os dados. do banco por hql. Sobrecarga do listarPorHql,
     * permitindo informar uma lista de parâmetros
     * @param hql Hql de busca no banco
     * @param parametros Mapa contendo os parâmetros necessários
     * @param maxResults Quantidade máxima de registros
     * @return lista de entidades
     * @throws X
     */
    List<E> listarPorHql(String hql, Map<String, Object> parametros, int maxResults) throws X;

    /**
     * Lista todos os dados. do banco por hql. Sobrecarga do listarPorHql,
     * permitindo informar uma lista de parâmetros
     * @param hql Hql de busca no banco
     * @param parametros Mapa contendo os parâmetros necessários
     * @param maxResults Quantidade máxima de registros
     * @return lista de entidades
     * @throws X
     */
    List<Object[]> consultarPorHql(String hql, Map<String, Object> parametros, int maxResults) throws X;

    /**
     * Procura uma entidade no banco baseada na entidade recebida
     * @param entidade Entidade buscada no banco
     * @param maxResults Quantidade máxima de registros
     * @return lista de entidades
     * @throws X
     */
    List<E> listarPorExemplo(E entidade, int maxResults) throws X;

    /**
     * Retorna uma lista de entidade pra ser utilizada num comboBox
     * @param classe Classe da entidade buscada no banco
     * @return lista de entidades
     * @throws X
     */
    List<E> listarParaCombo(Class<E> classe) throws X;

    /**
     * Valida uma entidade antes de realizar qualquer operação no banco
     * @param operacao Operação
     * @param entidade Entidade
     * @throws X
     */
    void validate(Integer operacao, E entidade) throws X;
}